home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / dispat.exe / DISPATCH.CPP < prev    next >
C/C++ Source or Header  |  1991-10-10  |  3KB  |  109 lines

  1.  
  2. // dispatch.cpp
  3. // joseph mcdermott  73740,3461  8 oct 1991
  4. // illustration only !!!!
  5. // safety not guaranteed !!!!!
  6. //
  7. // This program illustrates Borland's dynamic dispatch by value
  8. // --------------------------------------------------------
  9. // NOTE: compile with large model and far virtual tables
  10. //       If you chamnge these parameters, you must recompile 'dd.asm'.
  11. //       The code is based on 'windobj.cpp' and 'dd.asm'
  12. //       I have removed all dependencies on Windows 3.0 and OWL.
  13. //       This is a DOS program.
  14. // ---------------------------------------------------------
  15. #include <stdio.h>
  16.  
  17. #define getVptr(thisPtr)    (*(void far **)(thisPtr))
  18. #define WORD unsigned int
  19.  
  20. // now define dispatch indexes
  21. #define INDX_A   11
  22. #define INDX_B   12
  23. #define INDX_C   13
  24. #define INDX_D   14
  25.  
  26. class DispatchClass
  27. {
  28. public:
  29. void send(WORD, char *);
  30. virtual void method_a(char * ) = [INDX_A];  // [INDX_A] is the dispatch index
  31. virtual void method_b(char * ) = [INDX_B];
  32. virtual void method_c(char * ) = [INDX_C];
  33. virtual void method_d(char * ) = [INDX_D];
  34.  
  35. };
  36.  
  37. // the following typedef must match the virtual functions to be called
  38. // which should all have the same prototype pattern
  39. //
  40. // there is nothing special about  '(char *)'
  41. // any set of variables can be passed, but the prototypes should
  42. // be consistent
  43.  
  44. typedef void (DispatchClass::* far ClassMFP) (char *);
  45.  
  46. // 'Ddispatch' is in an assembly routine essentially identical to
  47. // 'dd.asm' in borland's owl source directory. This function searches
  48. // the virtual table for a matching index. It returns a function pointer
  49. // if a match is found, zero otherwize.  The compiler loads the indexes
  50. // into the virtual table (NOT a standard C++ feature !!)
  51.  
  52. extern "C" ClassMFP    Ddispatch(void far *vptr, WORD Dval);
  53.  
  54.  
  55. // 'send()' takes the dispatch index and calls the appropriate
  56. // virtual function if it exists.
  57.  
  58. void DispatchClass::send(WORD Dval, char *chr)
  59. {
  60.     ClassMFP MFP;
  61.  
  62.     // get method pointer by calling assembly routine
  63.     // returns 0 if none found
  64.     MFP = Ddispatch(getVptr(this), Dval);
  65.  
  66.     if (MFP)
  67.       (this->*MFP)(chr);           //  dispatch here !!!
  68.     else
  69.       /* default handling */
  70.       printf("No method found for value: %d \n", Dval);
  71. }
  72.  
  73. // a set of virtual functions Method_a to Method_d
  74. // that will receive the dynamic dispatch
  75.  
  76. void DispatchClass::method_a(char *s)
  77. {
  78.     printf("Method_a: %s\n", s);
  79. }
  80.  
  81. void DispatchClass::method_b(char *s)
  82. {
  83.     printf("Method_b: %s\n", s);
  84. }
  85.  
  86. void DispatchClass::method_c(char *s)
  87. {
  88.     printf("Method_c: %s\n", s);
  89. }
  90.  
  91.  
  92. void DispatchClass::method_d(char *s)
  93. {
  94.     printf("Method_d: %s\n", s);
  95. }
  96.  
  97. main()
  98. {
  99.     DispatchClass DC;
  100.  
  101.     DC.send(INDX_A, "send to a");
  102.     DC.send(INDX_B, "send to b");
  103.     DC.send(INDX_C, "send to c");
  104.     DC.send(INDX_D, "send to d");
  105.  
  106.     DC.send(99, "send to ???");     // no index for this one
  107.  
  108.  
  109. }